package com.wzy.validation;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.executable.ExecutableValidator;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ValidationTest
{
	// 验证器对象
	private Validator validator;
	// 待验证对象
	private UserInfo userInfo;
	// 验证结果
	private Set<ConstraintViolation<UserInfo>> result;

	// userinfoServeice 对象
	private Set<ConstraintViolation<UserInfoService>> serviceResult;

	/**
	 * 初始化
	 */
	@Before
	public void init()
	{
		validator = Validation.buildDefaultValidatorFactory().getValidator();

		userInfo = new UserInfo();
		// userInfo.setUserId("");
		// 可见notEmpty不会排除 " "（空白） ,但不能为null或""（空字符串）
		userInfo.setUserName(" ");
		userInfo.setPassword("123456");
		userInfo.setAge(22);
		Calendar calendar = Calendar.getInstance();
		calendar.set(2010, 11, 11);
		userInfo.setBirthday(new Date(calendar.getTimeInMillis()));
		List<UserInfo> friends = new ArrayList<UserInfo>();
		// friends.add(new UserInfo());
		userInfo.setFriends(friends);
	}

	/**
	 * 校验结果打印
	 */
	@After
	public void printResult()
	{
		serviceResult.forEach(i ->
		{
			System.out.println(i.getMessage());
		});
	}

	@Test
	public void test() throws Exception
	{
		result = validator.validate(userInfo);
	}

	// 列表级联验证
	@Test
	public void graphValidation() throws Exception
	{
		result = validator.validate(userInfo);
	}

	// 分组校验，只会校验被该组标识的字段，其他不会校验
	@Test
	public void groupValidation() throws Exception
	{
		result = validator.validate(userInfo, UserInfo.RegisterGroup.class);
	}

	// 如果高优先的校验项目没有通过那么就以直接跳出，不会再执行后续校验，节省资源
	@Test
	public void groupSequenceValidation() throws Exception
	{
		result = validator.validate(userInfo, UserInfo.Group.class);
	}


	// 方法输入参数进行约束注解校验
	@Test
	public void paramValidation() throws NoSuchMethodException
	{
		// 验证执行器
		ExecutableValidator executableValidator = validator.forExecutables();

		UserInfoService userInfoService = new UserInfoService();
		Method method = userInfoService.getClass().getMethod("setUserInfo", UserInfo.class);
		Object[] paramObjects = new Object[]{new UserInfo()};
		// 对方法的输入参数进行校验
		serviceResult = executableValidator.validateParameters(userInfoService, method, paramObjects);
	}

	//方法的返回值进行校验
	@Test
	public void returnValidation() throws Exception
	{
		ExecutableValidator executableValidator = validator.forExecutables();

		UserInfoService userInfoService = new UserInfoService();

		Method method = userInfoService.getClass().getMethod("getUserInfo");

		Object returnValue = method.invoke(userInfoService);

		serviceResult = executableValidator.validateReturnValue(userInfoService, method, returnValue);
	}

	// 对构造函数进行校验
	@Test
	public void constructorValidation() throws Exception
	{
		ExecutableValidator executableValidator = validator.forExecutables();

		Constructor<UserInfoService> constructor = UserInfoService.class.getConstructor(UserInfo.class);

		Object[] paramObjects = new Object[]{new UserInfo()};

		serviceResult = executableValidator.validateConstructorParameters(constructor, paramObjects);
	}
}
